#include "tthread.h"
#include "tlogger.h"
#include "errno.h"

namespace tlib
{
TThread::TThread() :
    m_bDetached(false), m_bActivated(false)
{

}

TThread::~TThread()
{
  Cannel();
}
#ifdef WIN32
void TThread::GlobleThread(void* param)
{
  ((TThread*) (param))->m_task();
}
#else
void* TThread::GlobleThread(void* param)
{
  ((TThread*) (param))->m_task();
  return NULL;
}
#endif

bool TThread::Run(TTask task)
{
  if (m_bActivated)
    return false;
  m_task = task;
#ifdef WIN32
  if ((m_th = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&TThread::GlobleThread, this, 0, &m_thid)) == NULL)
  return false;
#else
  if (pthread_create(&m_th, NULL, &TThread::GlobleThread, this) != 0)
    return false;
#endif
  m_bActivated = true;
  return true;
}

bool TThread::Cannel()
{
#ifdef WIN32
  if (m_bActivated)
  if (!::CloseHandle(m_th))
  return false;
#else
  if (m_bActivated)
    if (pthread_cancel(m_th) != 0)
      return false;
#endif
  m_bActivated = false;
  return true;
}

bool TThread::Join()
{
  if (m_bDetached || !m_bActivated)
    return false;
#ifdef WIN32
  if (!::WaitForSingleObject(m_th, INFINITE))
  return false;
#else
  if (pthread_join(m_th, NULL) != 0)
    return false;
#endif
  m_bActivated = false;
  return true;
}

bool TThread::SetDetach()
{
#ifdef WIN32
  return false;
#else
//  if (pthread_attr_setdetachstate(&m_attr, PTHREAD_CREATE_DETACHED) != 0)
//    return false;
//  m_bDetached = true;
  return false;
#endif
}

bool TThread::UnsetDetach()
{
#ifdef WIN32
  return false;
#else
//  if (pthread_attr_setdetachstate(&m_attr, PTHREAD_CREATE_JOINABLE) != 0)
//    return false;
//  m_bDetached = false;
  return false;
#endif
}

bool TThread::GetDetach()
{
#ifdef WIN32
  return false;
#else
  return m_bDetached;
#endif
}

bool TThread::IsActivated()
{
  return m_bActivated;
}
}
